/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.d2g.realestate.facade;

import br.com.d2g.realestate.persistence.Announce;
import br.com.d2g.realestate.webservice.client.ExchangeRate;
import br.com.d2g.realestate.webservice.client.ExchangeRateRestWSClient;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.xml.bind.JAXBException;

/**
 *
 * @author d2g
 */
@Stateless
public class AnnounceFacade extends AbstractFacade<Announce> {

    @PersistenceContext(unitName = "WebApplication2PU")
    private EntityManager em;

    protected EntityManager getEntityManager() {
        return em;
    }

    public AnnounceFacade() {
        super(Announce.class);
    }

    public List<Announce> searchAnnounceByOwnerAndCriteria(String ownerUsername, String address1, String postcode, Integer minNumberBathroom, Integer maxNumberBathroom, Integer minNumberBedroom,
            Integer maxNumberBedroom, String furnished, String type, String garden, Long minPrice, Long maxPrice, int[] range) {
        TypedQuery announceByOwnerQuery = this.em.createNamedQuery("Announce.findByOwnerAndCriterias", Announce.class);
        announceByOwnerQuery.setParameter("ownerUsername", ownerUsername);
        announceByOwnerQuery.setParameter("address", address1);
        announceByOwnerQuery.setParameter("postcode", postcode);
        announceByOwnerQuery.setParameter("minNumberBathroom", minNumberBathroom);
        announceByOwnerQuery.setParameter("maxNumberBathroom", maxNumberBathroom);
        announceByOwnerQuery.setParameter("minNumberBedroom", minNumberBedroom);
        announceByOwnerQuery.setParameter("maxNumberBedroom", maxNumberBedroom);
        announceByOwnerQuery.setParameter("furnished", furnished);
        announceByOwnerQuery.setParameter("type", type);
        announceByOwnerQuery.setParameter("garden", garden);
        announceByOwnerQuery.setParameter("minPrice", minPrice);
        announceByOwnerQuery.setParameter("maxPrice", maxPrice);
        announceByOwnerQuery.setMaxResults(range[1] - range[0]);
        announceByOwnerQuery.setFirstResult(range[0]);
        return announceByOwnerQuery.getResultList();
    }

    public int countAnnounceByOwnerAndCriteria(String ownerUsername, String address1, String postcode, Integer minNumberBathroom, Integer maxNumberBathroom, Integer minNumberBedroom,
            Integer maxNumberBedroom, String furnished, String type, String garden, Long minPrice, Long maxPrice) {
        TypedQuery announceByOwnerQuery = this.em.createNamedQuery("Announce.findByOwnerAndCriterias", Announce.class);
        announceByOwnerQuery.setParameter("ownerUsername", ownerUsername);
        announceByOwnerQuery.setParameter("address", address1);
        announceByOwnerQuery.setParameter("postcode", postcode);
        announceByOwnerQuery.setParameter("minNumberBathroom", minNumberBathroom);
        announceByOwnerQuery.setParameter("maxNumberBathroom", maxNumberBathroom);
        announceByOwnerQuery.setParameter("minNumberBedroom", minNumberBedroom);
        announceByOwnerQuery.setParameter("maxNumberBedroom", maxNumberBedroom);
        announceByOwnerQuery.setParameter("furnished", furnished);
        announceByOwnerQuery.setParameter("type", type);
        announceByOwnerQuery.setParameter("garden", garden);
        announceByOwnerQuery.setParameter("minPrice", minPrice);
        announceByOwnerQuery.setParameter("maxPrice", maxPrice);
        return announceByOwnerQuery.getResultList().size();
    }

    public List<Announce> searchAnnounceByCriteria(String ownerUsername, String address1, String postcode, Integer minNumberBathroom, Integer maxNumberBathroom, Integer minNumberBedroom,
            Integer maxNumberBedroom, String furnished, String type, String garden, Long minPrice, Long maxPrice, int[] range) {
        TypedQuery announceByCriteriaQuery = this.em.createNamedQuery("Announce.findByCriterias", Announce.class);
        announceByCriteriaQuery.setParameter("address", address1);
        announceByCriteriaQuery.setParameter("postcode", postcode);
        announceByCriteriaQuery.setParameter("minNumberBathroom", minNumberBathroom);
        announceByCriteriaQuery.setParameter("maxNumberBathroom", maxNumberBathroom);
        announceByCriteriaQuery.setParameter("minNumberBedroom", minNumberBedroom);
        announceByCriteriaQuery.setParameter("maxNumberBedroom", maxNumberBedroom);
        announceByCriteriaQuery.setParameter("furnished", furnished);
        announceByCriteriaQuery.setParameter("type", type);
        announceByCriteriaQuery.setParameter("garden", garden);
        announceByCriteriaQuery.setParameter("minPrice", minPrice);
        announceByCriteriaQuery.setParameter("maxPrice", maxPrice);
        announceByCriteriaQuery.setMaxResults(range[1] - range[0]);
        announceByCriteriaQuery.setFirstResult(range[0]);
        return announceByCriteriaQuery.getResultList();
    }

    public int countAnnounceByCriteria(String ownerUsername, String address1, String postcode, Integer minNumberBathroom, Integer maxNumberBathroom, Integer minNumberBedroom,
            Integer maxNumberBedroom, String furnished, String type, String garden, Long minPrice, Long maxPrice) {
        TypedQuery announceByOwnerQuery = this.em.createNamedQuery("Announce.findByCriterias", Announce.class);
        announceByOwnerQuery.setParameter("address", address1);
        announceByOwnerQuery.setParameter("postcode", postcode);
        announceByOwnerQuery.setParameter("minNumberBathroom", minNumberBathroom);
        announceByOwnerQuery.setParameter("maxNumberBathroom", maxNumberBathroom);
        announceByOwnerQuery.setParameter("minNumberBedroom", minNumberBedroom);
        announceByOwnerQuery.setParameter("maxNumberBedroom", maxNumberBedroom);
        announceByOwnerQuery.setParameter("furnished", furnished);
        announceByOwnerQuery.setParameter("type", type);
        announceByOwnerQuery.setParameter("garden", garden);
        announceByOwnerQuery.setParameter("minPrice", minPrice);
        announceByOwnerQuery.setParameter("maxPrice", maxPrice);
        return announceByOwnerQuery.getResultList().size();
    }

    public List<ExchangeRate> getAllCurrencies() {
        ExchangeRateRestWSClient client = new ExchangeRateRestWSClient();
        String response = client.getFindAll(String.class);
        List<ExchangeRate> exchangeRateList = parseListGBPConvertionRate(response);
        return exchangeRateList;
    }

    public ExchangeRate getGBPConvertionRate(String currency) {
        ExchangeRateRestWSClient client = new ExchangeRateRestWSClient();
        String response = client.getSearchRateToGBP(String.class, currency);
        ExchangeRate exchangeRate = parseSingleGBPConvertionRate(response);
        return exchangeRate;
    }

    private ExchangeRate parseSingleGBPConvertionRate(String xml) {
        ExchangeRate exchangeRate;
        int beginning;
        int end;

        exchangeRate = new ExchangeRate();

        beginning = xml.indexOf("<currency>") + "<currency>".length();
        end = xml.indexOf("</currency>");
        String currency = xml.substring(beginning, end);

        beginning = xml.indexOf("<currencyDescription>") + "<currencyDescription>".length();
        end = xml.indexOf("</currencyDescription>");
        String currencyDescription = xml.substring(beginning, end);

        beginning = xml.indexOf("<rateToGbp>") + "<rateToGbp>".length();
        end = xml.indexOf("</rateToGbp>");
        String rateToGbp = xml.substring(beginning, end);

        exchangeRate.setCurrency(currency);
        exchangeRate.setCurrencyDescription(currencyDescription);
        exchangeRate.setRateToGbp(Double.valueOf(rateToGbp));
        return exchangeRate;
    }

    private List<ExchangeRate> parseListGBPConvertionRate(String xml) {
        ExchangeRate exchangeRate;
        List<ExchangeRate> exchangeRateList = new ArrayList<ExchangeRate>();
        int beginning;
        int end;
        //for(int i=begining; i<end; i++ )
        while (true) {
            try {
                exchangeRate = new ExchangeRate();

                beginning = xml.indexOf("<currency>") + "<currency>".length();
                end = xml.indexOf("</currency>");
                String currency = xml.substring(beginning, end);

                beginning = xml.indexOf("<currencyDescription>") + "<currencyDescription>".length();
                end = xml.indexOf("</currencyDescription>");
                String currencyDescription = xml.substring(beginning, end);

                beginning = xml.indexOf("<rateToGbp>") + "<rateToGbp>".length();
                end = xml.indexOf("</rateToGbp>");
                String rateToGbp = xml.substring(beginning, end);

                exchangeRate.setCurrency(currency);
                exchangeRate.setCurrencyDescription(currencyDescription);
                exchangeRate.setRateToGbp(Double.valueOf(rateToGbp));

                exchangeRateList.add(exchangeRate);

                if (beginning == -1 || end == -1) {
                    break;
                }
                xml = xml.substring(end + + "</rateToGbp>".length());
            } catch (Exception e) {
                return exchangeRateList;
            }
        }
        return exchangeRateList;
    }
}
